/**
 * 在这里定义和用户相关的路由处理函数，供 /router/user.js 模块进行调用
 */
const bcrypt = require('bcryptjs')
const db = require('../db/index')
// 用这个包来生成 Token 字符串
const jwt = require('jsonwebtoken')
// 导入配置文件
const config = require('../config')
// 注册用户的处理函数
exports.regUser = (req, res) => {
	// 接收表单数据
	const userinfo = req.body

	// 检查返回的信息
	console.log(userinfo)

	// 判断数据是否合法
	if (!userinfo.username || !userinfo.password) {
		return res.send({ status: 1, message: '用户名或密码不能为空！' })
	}

	const sql = `select * from ev_user where username=?`

	db.query(sql, [userinfo.username], function (err, results) {
		// 执行 SQL 语句失败
		if (err) {
			// return res.send({ status: 1, message: err.message })
			return res.cc(err)
		}
		// 大于0就说明找到该用户了，即用户名被占用
		if (results.length > 0) {
			// return res.send({
			// 	status: 1,
			// 	message: '用户名被占用，请更换其他用户名！',
			// })
			return res.cc('用户名被占用，请更换其他用户名！')
		}
		// 对用户的密码,进行 bcrype 加密，返回值是加密之后的密码字符串
		userinfo.password = bcrypt.hashSync(userinfo.password, 10)
		// console.log(userinfo.password)

		const sql = 'insert into ev_user set ?'
		db.query(
			sql,
			{ username: userinfo.username, password: userinfo.password },
			function (err, results) {
				// 执行 SQL 语句失败
				//if (err) return res.send({ status: 1, message: err.message })
				if (err) return res.cc(err)
				// SQL 语句执行成功，但影响行数不为 1，所谓的影响行数指的是数据库中数据有多少行在执行后收到影响
				// if (results.affectedRows !== 1) {
				// 	return res.send({
				// 		status: 1,
				// 		message: '注册用户失败，请稍后再试！',
				// 	})
				// }
				if (results.affectedRows !== 1)
					return res.cc('注册用户失败，请稍后再试！')
				// 注册成功
				// res.send({ status: 0, message: '注册成功！' })
				res.cc('注册成功！', 0, true)
			}
		)
	})
	// res.send('register OK')
}

// 登录的处理函数
exports.login = (req, res) => {
	const userinfo = req.body

	const sql = `select * from ev_user where username=?`

	db.query(sql, userinfo.username, function (err, results) {
		// 执行 SQL 语句失败
		if (err) return res.cc(err)
		// 执行 SQL 语句成功，但是查询到数据条数不等于 1
		if (results.length !== 1) return res.cc('登录失败！')

		// 拿着用户输入的密码,和数据库中存储的密码进行对比
		const compareResult = bcrypt.compareSync(
			userinfo.password,
			results[0].password
		)
		// console.log(results[0])
		// 如果对比的结果等于 false, 则证明用户输入的密码错误
		if (!compareResult) {
			return res.cc('登录失败！')
		}

		const user = { ...results[0], password: '', user_pic: '' }
		// res.send('OK')

		// 在登录处理函数中生成 Token 字符串
		const tokenStr = jwt.sign(user, config.jwtSecretKey, {
			expiresIn: config.expiresIn, // token 有效期为 10 个小时
		})

		res.send({
			status: 0,
			message: '登录成功！',
			// 为了方便客户端使用 Token，在服务器端直接拼接上 Bearer 的前缀
			token: 'Bearer ' + tokenStr,
		})
	})
	// res.send('login OK')
}

const captcha = require('svg-captcha') //1.引入的模块
const { array } = require('joi')

//获取验证码处理函数
exports.getCaptcha = (req, res) => {
	const cap = captcha.create({
		size: 4, //长度
		ignoreChars: '0o1il', //排除字符
		noise: 3, //干扰线条数
		width: 120, // 宽度
		height: 36, // 高度
		color: true, // 验证码字符是否有颜色，默认是没有,如果设置了背景颜色，那么默认就是有字符颜色
		background: '#fff', // 背景色 可以自己改
	})
	// req.session.captcha = cap.text
	// console.log(req.session)
	// res.type('svg') //响应类型

	res.send(cap)
}

/*
 *以下是uniapp小程序实现的接口功能
 */

// 以邮箱/用户名的密码登录
exports.loginByEmail_Pwd = (req, res) => {
	let { username, password } = req.body

	// 这是邮箱的正则表达式判断
	let email_reg =
		/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/

	let sqlStr = ``
	if (email_reg.test(username)) {
		// console.log(req.body)//要注意传给你的是表单/JSON文件格式
		sqlStr = `select * from ev_user where email='${username}'`
	} else {
		sqlStr = `select * from ev_user where username='${username}'`
	}

	db.query(sqlStr, function (err, results) {
		if (err) return res.cc(err)
		// console.log(results)
		if (results.length !== 1)
			return res.cc('登录失败！没找到这个用户或邮箱')

		const compareResult = bcrypt.compareSync(password, results[0].password)
		if (!compareResult) {
			return res.cc('登录失败！密码输入错误')
		}
		const user = { ...results[0], password: '', user_pic: '' }
		const tokenStr = jwt.sign(user, config.jwtSecretKey, {
			expiresIn: config.expiresIn, // token 有效期为 10 个小时
		})
		res.send({
			success: true,
			status: 0,
			message: '登录成功！',
			token: 'Bearer ' + tokenStr,
		})
	})
}

/**
 * 验证邮箱的验证码，然后登录成功
 */
exports.loginByEmail_Code = (req, res) => {
	let { verCode, email } = req.body
	//先查询数据库这个邮箱有没有存
	const sql = `select * from ev_user where email='${email}'`
	db.query(sql, function (err, results) {
		if (err) {
			res.cc(err)
		}

		if (results.length !== 1) {
			res.cc('该邮箱未注册')
		}

		const user = { ...results[0], password: '', user_pic: '' }
		const tokenStr = jwt.sign(user, config.jwtSecretKey, {
			expiresIn: config.expiresIn, // token 有效期为 10 个小时
		})
		console.log(verCode, codeObj)
		if (codeObj[email] == verCode) {
			res.send({
				success: true,
				status: 0,
				message: '验证通过',
				token: 'Bearer ' + tokenStr,
			})
		} else {
			res.cc('验证不通过')
		}
	})
}

/**
 *发送验证码到指定邮箱
 */
let codeObj = {}
const Mail = require('../db/mail')
exports.getEmailCode = (req, res) => {
	//根据表单获取数据
	let mail = req.query.email
	//数组存放随机字母+数字，a-z：97-122，A-Z：65-90，0-9：48-57。
	var ASCII_to_letter = []
	for (let i = 97; i <= 122; i++) {
		ASCII_to_letter.push(String.fromCharCode(i))
	}
	for (let j = 65; j <= 90; j++) {
		ASCII_to_letter.push(String.fromCharCode(j))
	}
	for (let k = 48; k <= 57; k++) {
		ASCII_to_letter.push(String.fromCharCode(k))
	}
	//生成随机校验码
	let code = ''
	for (var z = 0; z < 6; z++) {
		var index = Math.floor(Math.random() * ASCII_to_letter.length)
		code += ASCII_to_letter[index]
	}
	console.log(code)
	//根据邮件存放验证码
	codeObj[mail] = code
	//发送验证码到从get请求获取到邮件名
	Mail.send(mail, code, (state) => {
		if (state === 1) {
			res.send({
				success: true,
				status: 0,
				message: '发送邮箱成功',
			})
		} else {
			res.cc('发送失败')
		}
	})
}

// 注册+邮箱版
exports.registerAddEmail = (req, res) => {
	const userinfo = req.body
	if (!userinfo.username || !userinfo.password) {
		return res.cc('用户名或密码不能为空！')
	}
	const sql = `select * from ev_user where username=? or email=?`
	db.query(sql, [userinfo.username, userinfo.email], function (err, results) {
		if (err) {
			return res.cc(err)
		}
		if (results.length > 0) {
			return res.cc('用户名或邮箱被占用，请更换其他用户名！')
		}
		userinfo.password = bcrypt.hashSync(userinfo.password, 10)
		const sql = 'insert into ev_user set ?'
		db.query(
			sql,
			{
				username: userinfo.username,
				password: userinfo.password,
				email: userinfo.email,
			},
			function (err, results) {
				if (err) return res.cc(err)
				if (results.affectedRows !== 1)
					return res.cc('注册用户失败，请稍后再试！')
				res.cc('注册成功！', 0, true)
			}
		)
	})
}

//轮播图
exports.getCarousel = (req, res) => {
	const sqlStr = 'select * from carousel'
	db.query(sqlStr, (err, result) => {
		//转换成数组
		var arr = []
		for (var i in result) {
			arr.push(result[i])
		}
		if (err) {
			res.cc(err)
		}
		if (result) {
			res.send({
				success: true,
				status: 0,
				message: '查找成功',
				data: {
					items: arr,
				},
			})
		}
	})
}

//博客列表
//文章列表显示处理函数
// 左连接，根据cate_id查找到cates的name
exports.cateName = (req, res) => {
	const sql = `select aleft.Id as 'Id',
    aleft.title as 'title',
    aleft.content as 'content',
    aleft.pub_date as 'pub_date',
    aleft.state as 'state',
    aleft.is_delete as 'is_delete',
    aleft.summary as 'summary',
    aright.name as 'cate_name'
    from ev_articles as aleft left join ev_article_cate as aright on aleft.cate_id=aright.id
    where aleft.is_delete=0 and aleft.state<>'草稿' order by aleft.Id asc`
	db.query(sql, (err, results) => {
		//转换成数组
		var arr = []
		for (var i in results) {
			arr.push(results[i])
		}

		if (err) return res.cc(err)
		res.send({
			success: true,
			status: 0,
			message: '获取类别名成功',
			data: {
				items: arr,
			},
		})
	})
}

//模糊搜索文章标题涉及的到的内容
exports.ArtSearch = (req, res) => {
	let mess = req.body.SearchName
	// console.log(req.body)
	const sql = `select aleft.Id as 'Id',
    aleft.title as 'title',
    aleft.content as 'content',
    aleft.pub_date as 'pub_date',
    aleft.state as 'state',
    aleft.is_delete as 'is_delete',
    aleft.summary as 'summary',
    aright.name as 'cate_name'
    from ev_articles as aleft left join ev_article_cate as aright on aleft.cate_id=aright.id
    where (aleft.is_delete=0 and aleft.state<>'草稿')
    and (aleft.title like '%${mess}%' or aright.name like '%${mess}%')
    order by aleft.Id asc`

	db.query(sql, (err, results) => {
		// console.log(results)
		//转换成数组
		var arr = []
		for (var i in results) {
			arr.push(results[i])
		}
		if (err) return res.cc(err)
		res.send({
			success: true,
			status: 0,
			message: '模糊搜索成功',
			data: {
				items: arr,
			},
		})
	})
}

//根据Id获取文章
exports.getArticleById = (req, res) => {
	const sql = `select
    aleft.Id as 'Id',
    aleft.title as 'title',
    aleft.content as 'content',
    aleft.pub_date as 'pub_date',
    aright.username as 'username'
    from ev_articles as aleft left join ev_user as aright on aleft.author_id = aright.id
    where aleft.Id=?`
	db.query(sql, req.params.Id, (err, results) => {
		// 执行 SQL 语句失败
		if (err) return res.cc(err)

		// SQL 语句执行成功，但是没有查询到任何数据
		if (results.length !== 1) return res.cc('获取文章数据失败！')

		// 把数据响应给客户端
		res.send({
			success: true,
			status: 0,
			message: '获取文章数据成功！',
			data: {
				productArticle: results[0],
			},
		})
	})
}

// 获取文章分类列表数据的处理函数
exports.getArticleCates = (req, res) => {
	const sql =
		'select * from ev_article_cate where is_delete=0 order by id asc'

	db.query(sql, (err, results) => {
		// 1. 执行 SQL 语句失败
		if (err) return res.cc(err)

		// 2. 执行 SQL 语句成功
		res.send({
			success: true,
			status: 0,
			message: '获取文章分类列表成功！',
			data: {
				data: results,
			},
		})
	})
}
